# -*- coding: utf-8 -*-
import json
import logging

from common.admin import db as admin_user
from common.admin.model import ACTION
from common.admin.model import ROLE
from common.utils import JsonResponse
from common.utils.exceptions import PermissionError
from common.utils.ip_to_city import get_city

_LOGGER = logging.getLogger('hydra')


def has_perm(target_perm, user_perm):
    if not target_perm:
        return True
    if not user_perm:
        return False
    user_perm = user_perm.split('|')
    target_perm = target_perm.split('|')
    intersects = list(set(user_perm) & set(target_perm))
    return False if not intersects else True


def check_perm(url_array, perm, role, user_perm):
    if role == ROLE.ADMIN:
        return True
    length = len(url_array)
    while length >= 1:
        url = '/'.join(url_array[0:length])
        if not url.endswith('/'):
            url += '/'
        k = admin_user.get_perm(url, perm)
        if k and k.min_role <= role and (role == ROLE.ADMIN or has_perm(k.user_perm, user_perm)):
            return True
        length -= 1
    return False


def process_admin_request(req, user_id, token):
    if not admin_user.check_token_vaild(user_id, token) and not req.path.startswith('/hydra/admin/user/login/') \
            and not (req.path == '/hydra/admin/user/' and req.method in {'POST': 1}):
        return JsonResponse(dict(
            status=PermissionError.STATUS,
            msg=u'token过期，请重新登陆!'),
            status=PermissionError.HTTPCODE)
    info = admin_user.get_online_info(user_id, token)
    if info and info.deleted == 0:
        req.user_id = user_id
        user = admin_user.get_user(user_id)
        if user.role > 0:
            req.user = user
            return
        else:
            return JsonResponse(dict(
                status=PermissionError.STATUS,
                msg=str("user is forbidden or not activited")),
                status=PermissionError.HTTPCODE)


def process_admin_response(req, resp):
    resource = req.path.replace('/hydra/admin/', '')
    try:

        content = json.loads(resp.content)
        status = content['status']
        if status != 0:
            return
        data = content['data']

        if isinstance(data, dict):
            resource_id = ""
            if 'id' in data:
                resource_id = data['id']
            record = {
                'resource': resource,
                'resource_id': resource_id,
                'action': ACTION[req.method],
                'content': req.body,
                'ip': req.ip,
                'city': get_city(req.ip),
                'operator': req.user_id
            }

            if req.path.startswith('/hydra/admin/user/login'):
                record['operator'] = resource_id
                record['content'] = 'login'
            admin_user.insert_record(record)
        elif isinstance(data, list):
            if resource == 'manage/get_perm_tree/': 
                return

            for d in data:
                if 'id' not in d:
                    continue
                else:
                    admin_user.insert_record({
                    'resource': resource,
                    'resource_id': resource_id,
                    'action': ACTION[req.method],
                    'content': req.body,
                    'param': json.dumps(d, ensure_ascii=False,
                                          cls=EnhencedEncoder),
                    'operator': req.user_id
                    })
    except (ValueError, TypeError) as e:
        _LOGGER.exception(e)


class UserMiddleware(object):
    """get user_id and token from header"""

    def process_request(self, req):

        if req.META.has_key('HTTP_X_FORWARDED_FOR'):
            ip = req.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = req.META['REMOTE_ADDR']
        req.ip = ip
        if req.path.startswith('/hydra/admin'):
            user_id = req.COOKIES.get('hydra_user_id')
        else:
            user_id = req.COOKIES.get('pay_user_id')

        token = req.COOKIES.get('pay_user_token')
        agency_token = req.COOKIES.get('agency_user_token')

        if req.META.has_key('HTTP_USERPROFILE') and not token and not user_id:
            uservar = str(req.META['HTTP_USERPROFILE'])
            userinfo = json.loads(uservar)
            user_id = userinfo["user_id"]
            agency_token = userinfo["token"]
            token = userinfo["token"]

        if user_id and (token or agency_token):
            try:
                user_id = long(user_id)
            except ValueError:
                _LOGGER.error('user id format wrong!')
                req.user_id = None
                return
            if req.path.startswith('/hydra/admin'):
                return process_admin_request(req, user_id, token)

        req.user_id = req.user = None

    def process_response(self, req, resp):

        if req.method not in ACTION:
            return resp
        if req.path.startswith('/hydra/admin'):
            process_admin_response(req, resp)
        return resp
